package org.apache.rocketmq.console.service;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.rocketmq.common.AclConfig;
import org.apache.rocketmq.common.PlainAccessConfig;
import org.apache.rocketmq.common.protocol.body.ClusterInfo;
import org.apache.rocketmq.common.protocol.route.BrokerData;
import org.apache.rocketmq.console.model.Account;
import org.apache.rocketmq.tools.admin.MQAdminExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author caiwl
 * @date 2021/6/1 15:46
 */
@Service
public class AccountlService {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MQAdminExt mqAdminExt;

    public Map<String, Object> list() {
        Map<String, Object> resultMap = Maps.newHashMap();
        List<Account> accounts = Lists.newArrayList();
        try {
            ClusterInfo clusterInfo = mqAdminExt.examineBrokerClusterInfo();
            for (BrokerData brokerData : clusterInfo.getBrokerAddrTable().values()) {
                for (String brokerAddr : brokerData.getBrokerAddrs().values()) {
                    AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(brokerAddr);
                    List<PlainAccessConfig> configs = aclConfig.getPlainAccessConfigs();
                    if (configs != null && configs.size() > 0) {
                        for (PlainAccessConfig config : configs) {
                            Account account = new Account();
                            account.setCluster(brokerData.getCluster());
                            account.setBrokerName(brokerData.getBrokerName());
                            account.setBrokerAddr(brokerAddr);
                            BeanUtils.copyProperties(config, account);
                            accounts.add(account);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("Failed to examine Broker Cluster ACL Info", e);
        }
        resultMap.put("accounts", accounts);
        return resultMap;
    }

    public boolean createOrUpdateAccount(Account account) {
        PlainAccessConfig config = new PlainAccessConfig();
        BeanUtils.copyProperties(account, config);
        try {
            mqAdminExt.createAndUpdatePlainAccessConfig(account.getBrokerAddr(), config);
        } catch (Exception e) {
            log.error("Failed to mqadmin updateAclConfig", e);
            throw Throwables.propagate(e);
        }
        return true;
    }

    public boolean deleteAccount(String brokerAddr, String accessKey) {
        try {
            mqAdminExt.deletePlainAccessConfig(brokerAddr, accessKey);
        } catch (Exception e) {
            log.error("Failed to mqadmin deleteAccessConfig", e);
            throw Throwables.propagate(e);
        }
        return true;
    }
}
